package cn.wolfcdoe.audit.service.impl;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

import cn.wolfcdoe.audit.domain.BusBpmnInfo;
import cn.wolfcdoe.audit.dto.AudCarPackageDTO;
import cn.wolfcdoe.audit.dto.AudedCarPackageDTO;
import cn.wolfcdoe.audit.vo.TaskHistoryVo;
import cn.wolfcdoe.business.domain.BusServiceItem;
import cn.wolfcdoe.business.mapper.BusServiceItemMapper;
import cn.wolfcdoe.business.mapper.BusStatementItemMapper;
import cn.wolfcdoe.common.constant.AutdConstants;
import cn.wolfcdoe.common.constant.BusServiceItemConstants;
import cn.wolfcdoe.common.utils.DateUtils;
import cn.wolfcdoe.common.utils.SecurityUtils;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.CommentEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskInfo;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.bcel.generic.I2F;
import org.apache.poi.ss.formula.udf.AggregatingUDFFinder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcdoe.audit.mapper.AudCarPackageMapper;
import cn.wolfcdoe.audit.domain.AudCarPackage;
import cn.wolfcdoe.audit.service.IAudCarPackageService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;

/**
 * 套餐审核Service业务层处理
 *
 * @author zhuo
 * @date 2023-04-17
 */
@Service
public class AudCarPackageServiceImpl implements IAudCarPackageService {
    @Autowired
    private AudCarPackageMapper audCarPackageMapper;
    @Resource
    private RuntimeService runtimeService;

    @Resource
    private BusServiceItemMapper busServiceItemMapper;

    @Resource
    private TaskService taskService;

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private HistoryService historyService;


    /**
     * 查询套餐审核
     *
     * @param id 套餐审核主键
     * @return 套餐审核
     */
    @Override
    public AudCarPackage selectAudCarPackageById(Long id) {
        return audCarPackageMapper.selectAudCarPackageById(id);
    }

    /**
     * 查询套餐审核列表
     *
     * @param audCarPackage 套餐审核
     * @return 套餐审核
     */
    @Override
    public List<AudCarPackage> selectAudCarPackageList(AudCarPackage audCarPackage) {
        return audCarPackageMapper.selectAudCarPackageList(audCarPackage);
    }

    /**
     * 新增套餐审核
     *
     * @param audCarPackage 套餐审核
     * @return 结果
     */
    @Override
    public int insertAudCarPackage(AudCarPackage audCarPackage) {
        audCarPackage.setCreateTime(DateUtils.getNowDate());
        return audCarPackageMapper.insertAudCarPackage(audCarPackage);
    }

    /**
     * 修改套餐审核
     *
     * @param audCarPackage 套餐审核
     * @return 结果
     */
    @Override
    public int updateAudCarPackage(AudCarPackage audCarPackage) {
        return audCarPackageMapper.updateAudCarPackage(audCarPackage);
    }

    /**
     * 批量删除套餐审核
     *
     * @param ids 需要删除的套餐审核主键
     * @return 结果
     */
    @Override
    public int deleteAudCarPackageByIds(Long[] ids) {
        return audCarPackageMapper.deleteAudCarPackageByIds(ids);
    }

    /**
     * 删除套餐审核信息
     *
     * @param id 套餐审核主键
     * @return 结果
     */
    @Override
    public int deleteAudCarPackageById(Long id) {
        return audCarPackageMapper.deleteAudCarPackageById(id);
    }


    //发起审核
    @Override
    public int serviceItemStartAudit(AudCarPackageDTO audCarPackageDTO) {
        //根据服务项id查询出对应的服务项
        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(audCarPackageDTO.getId());
        //因为bus_service_item表中的id和aud_car_package表中的service_item_id是属于关联关系
        String businessKey = audCarPackageDTO.getId().toString();
        Map<String, Object> variables = new HashMap<>();//设置流程变量值

        variables.put("disCountPrice", busServiceItem.getDiscountPrice().longValue());
        variables.put("shopOwnerId", audCarPackageDTO.getShopOwnerId());
        //判断财务是否存在不存在则不设置
        if (audCarPackageDTO.getFinanceId() != null) {
            variables.put("financeId", audCarPackageDTO.getFinanceId());
        }
        //key写死了需要改进 查询对应的流程实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("bus_car_package", businessKey, variables);
        busServiceItem.setAuditStatus(BusServiceItemConstants.AUDIT_STATUS_PENDING);
        busServiceItemMapper.updateBusServiceItem(busServiceItem);
        //最后往aud_car_package表中存数据
        AudCarPackage audCarPackage = new AudCarPackage();
        //把数据设置到AudCarPackage中
        audCarPackage.setInstanceId(processInstance.getId());                       //实例id
        audCarPackage.setServiceItemId(busServiceItem.getId());                     //服务项id
        audCarPackage.setServiceItemName(busServiceItem.getName());                 //服务项名称
        audCarPackage.setServiceItemPrice(busServiceItem.getDiscountPrice());       //折扣价
        audCarPackage.setServiceItemInfo(busServiceItem.getInfo());                 //备注信息
        audCarPackage.setStatus(AutdConstants.CAR_PACKAGE_STATUS_PENDING);          //审核中


        audCarPackage.setCreatorId(SecurityUtils.getUserId().toString());           //创建者id
        audCarPackage.setCreateTime(DateUtils.getNowDate());                        //创建时间
        audCarPackage.setCreateBy(SecurityUtils.getUsername());                     //创建人姓名
        audCarPackage.setInfo(busServiceItem.getInfo());                            //备注信息


        return audCarPackageMapper.insertAudCarPackage(audCarPackage);
    }

    /**
     * 查询代办
     * @return
     */
    @Override
    @Transactional
    public List<AudCarPackage> listToDoCarPackage() {
        String userId = SecurityUtils.getLoginUser().getUserId().toString();
        //查询当前用户的审核任务
        List<Task> tasks = taskService.createTaskQuery()
                .taskAssignee(userId)               //查询指定用户的任务
                .processDefinitionKey("bus_car_package")       //查询那个流程的的任务
                .list();

        //任务为0返回空集合
        if (tasks.size() == 0) {
            return Collections.emptyList();
        }

        //获取流程实例id
        Set<String> processInstanceIds = tasks.stream().map(Task::getProcessInstanceId)
                .collect(Collectors.toSet());

        //id为空放回空集合
        if (processInstanceIds.size() == 0) {
            return Collections.emptyList();
        }
        //根据流程实例id查询出aud_car_package表中的数据
        return audCarPackageMapper.selectAudCarPackageByprocessInstanceId(processInstanceIds);
    }

    @Override
    @Transactional
    public void auditServiceItem(AudedCarPackageDTO audedCarPackageDTO) {
        //获取流程实例id
        String processInstanceId = audedCarPackageDTO.getProcessInstanceId();
        //备注
        String info = SecurityUtils.getUsername() + ":" + audedCarPackageDTO.getInfo();

        Task task = taskService.createTaskQuery()
                .taskAssignee(SecurityUtils.getUserId().toString())
                .processInstanceId(processInstanceId)
                .singleResult();
        //添加审核备注
        taskService.addComment(task.getId(), processInstanceId, info);
        HashMap<String, Object> variables = new HashMap<>();
        boolean auditStatus = audedCarPackageDTO.isAuditStatus();
        variables.put("shopOwner", auditStatus);

        //任务开始执行
        taskService.complete(task.getId(),variables);
        //判断是否审核通过
        if (auditStatus) {
            if (taskService.createTaskQuery()
                    .processInstanceId(processInstanceId)
                    .list().size() == 0) {
                //把审核信息的数据和服务项数据状态该成通过
               AudCarPackage  audCarPackage =  audCarPackageMapper.selectAudCarPackageByProcessInstanceId(processInstanceId);
               audCarPackage.setStatus(AutdConstants.CAR_PACKAGE_STATUS_SUCCESS);
               audCarPackageMapper.updateAudCarPackage(audCarPackage);
               BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(audCarPackage.getServiceItemId());
               busServiceItem.setAuditStatus(BusServiceItemConstants.AUDIT_STATUS_SUCCESS);
               busServiceItemMapper.updateBusServiceItem(busServiceItem);
            }

        } else {//审核拒绝
            //把审核信息的数据和服务项数据状态该成及拒绝
            AudCarPackage  audCarPackage =  audCarPackageMapper.selectAudCarPackageByProcessInstanceId(processInstanceId);
            audCarPackage.setStatus(AutdConstants.CAR_PACKAGE_STATUS_FALL);
            audCarPackageMapper.updateAudCarPackage(audCarPackage);
            BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(audCarPackage.getServiceItemId());
            busServiceItem.setAuditStatus(BusServiceItemConstants.AUDIT_STATUS_FALL);
            busServiceItemMapper.updateBusServiceItem(busServiceItem);
        }
    }

    @Override
    public InputStream getInputStream(String instanceId) {


        //根据流程实例id查询出流程定义
        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(instanceId)
                .singleResult();

        //获取流程定义id
        String processDefinitionId = processInstance.getProcessDefinitionId();
        //查询执行的任务获取任务的节点
        Task task = taskService.createTaskQuery()
                .processInstanceId(instanceId)
                .singleResult();
        if (task==null) {
            DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
            //bpmnModel对象用来封装画的流程图
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            return generator.generateDiagram(bpmnModel,
                    Collections.emptyList(),
                    Collections.emptyList(),
                    "宋体",
                    "宋体",
                    "宋体");
        }
        //获取任务的节点
        String executionId = task.getExecutionId();
        //获取节点在流程图上的坐标
        List<String> activityIds = runtimeService.getActiveActivityIds(executionId);


        // 查看流程图
        //在内存中画图对象
        DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
        //bpmnModel对象用来封装画的流程图
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        return generator.generateDiagram(bpmnModel,
                activityIds,
                Collections.emptyList(),
                "宋体",
                "宋体",
                "宋体");
    }

    @Override
    public List<AudCarPackage> listDoneCarPackage() {
        String userId = SecurityUtils.getLoginUser().getUserId().toString();
        //查询当前用户的历史审核任务
        List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(userId)               //查询指定用户的任务
                .processDefinitionKey("bus_car_package")       //查询那个流程的的任务
                .finished()             //查询语句审核过的任务
                .list();

        //任务为0返回空集合
        if (tasks.size() == 0) {
            return Collections.emptyList();
        }

        //获取流程实例id
        Set<String> processInstanceIds = tasks.stream().map(TaskInfo::getProcessInstanceId)
                .collect(Collectors.toSet());

        //id为空放回空集合
        if (processInstanceIds.size() == 0) {
            return Collections.emptyList();
        }
        //根据流程实例id查询出aud_car_package表中的数据
        return audCarPackageMapper.selectAudCarPackageByprocessInstanceId(processInstanceIds);
    }

    @Override
    public List<TaskHistoryVo> queryAuditHistories(String instanceId) {
        //查询对应实例下的任务(已审核和没有审核过的)
        List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(instanceId)
                .list();

        if (tasks.size() == 0) {
            return Collections.emptyList();
        }
        List<TaskHistoryVo> list = new ArrayList<>();
        //遍历任务吧数据封装到自定义的对象中
        for (HistoricTaskInstance task : tasks) {
            TaskHistoryVo taskHistoryVo = new TaskHistoryVo();
            taskHistoryVo.setTaskName(task.getName());
            Date startTime = task.getStartTime();
            taskHistoryVo.setStartTime(startTime);
            Date endTime = task.getEndTime();
            taskHistoryVo.setEndTime(endTime);            //没有执行完的任务可能没有结束时间
            if (task.getEndTime()!= null){
                //计算耗时
                String datePoor = DateUtils.getDatePoor(endTime, startTime);
                taskHistoryVo.setDuration(datePoor);
            }
            //查询任务对应的审核备注
            List<Comment> comments = taskService.getTaskComments(task.getId(), CommentEntity.TYPE_COMMENT);
            StringBuilder info = new StringBuilder();
            if (comments.size() >0) {
                //遍历把备注内容拼接
                for (Comment comment : comments) {
                    info.append(comment.getFullMessage());
                }
                taskHistoryVo.setInfo(info.toString());
            }
            //把每条历史记录都存到集合中
            list.add(taskHistoryVo);
        }
        return list;
    }


    @Override
    public void cancelCarPackage(String instanceId) {

        runtimeService.deleteProcessInstance(instanceId,"无删除原因");

        AudCarPackage  audCarPackage =  audCarPackageMapper.selectAudCarPackageByProcessInstanceId(instanceId);
        audCarPackage.setStatus(AutdConstants.CAR_PACKAGE_STATUS_CANCELED);
        audCarPackageMapper.updateAudCarPackage(audCarPackage);
        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(audCarPackage.getServiceItemId());
        busServiceItem.setAuditStatus(BusServiceItemConstants.AUDIT_STATUS_FALL);
        busServiceItemMapper.updateBusServiceItem(busServiceItem);
    }
}
